//
// ConsumerParser.hpp for  in ~/Projets/
//
// Made by Jonathan
// Login   <herpec_j@epitech.net>
//
// Started on  Tue Sep 10 09:58:11 2013 Jonathan
// Last update Thu Sep 26 00:19:25 2013 Jonathan
//

#ifndef			CONSUMERPARSER_HPP_
# define		CONSUMERPARSER_HPP_

# include		<map>
# include		<stack>
# include		<vector>
# include		<list>
# include		<iostream>
# include		<fstream>

# include		"Parsing/ProducterStream.hpp"

# define		ZERO_OR_ONE(X)					       \
  SaveContext();							       \
  if ((X))								       \
    {									       \
      RestoreContext(false);						       \
    }									       \
  else									       \
    {									       \
      RestoreContext(true);						       \
    }									       \

# define		ZERO_OR_MANY(X)	\
  SaveContext();			\
  while (true)				\
    {					\
  if ((X))				\
    {					\
  RestoreContext(false);		\
  SaveContext();			\
    }					\
  else					\
    {					\
  RestoreContext(true);			\
  break;				\
    }					\
    }					\

# define		ONE_OR_MANY(X)					       \
  SaveContext();							       \
  if ((X))								       \
    {									       \
      RestoreContext(false);						       \
      ZERO_OR_MANY(X)							       \
    }									       \
  else									       \
    {									       \
      RestoreContext(true);						       \
      return (false);							       \
    }									       \

namespace		Parsing
{
  class			ConsumerParser
  {
  private:

  protected:
    ProducterStream	&mStream;
    std::map<std::string, int> mMap;
    std::string		mBuffer;
    int			mCol;
    std::stack<int>	mStack;

    ConsumerParser(ConsumerParser const &rCopy);
    ConsumerParser	&operator=(ConsumerParser const &rCopy);

    bool		FeedBuffer(void);
    void		SaveContext(void);
    void		RestoreContext(bool rRestore);

  public:
    ConsumerParser(ProducterStream &rStream);
    virtual ~ConsumerParser(void);

    bool		Read(void);
    bool		SkipSpaces(void);
    bool		ReadText(char *rText, bool rSkipSpaces = true);
    bool		ReadEOF(void);
    bool		ReadUntil(char rC);
    bool		ReadUntil(std::list<char> const &rCharList);
    bool		ReadUntilEOF(void);
    bool		ReadInteger(bool rSkipSpaces = true);
    bool		ReadIdentifier(bool rSkipSpaces = true);
    bool		PeekChar(char rC);
    bool		ReadChar(char rC, bool rSkipSpaces = true);
    bool		ReadRange(char rBegin, char rEnd, bool rSkipSpaces = true);
    bool		BeginCapture(std::string rTag, bool rSkipSpaces = true);
    bool		EndCapture(std::string rTag, std::string &rOut);
  };
};

#endif			/* CONSUMERPARSER_HPP_ */
